<?php

namespace app\common\service;
use app\common\model\MoneyCensusModel;
use app\common\model\MoneyRecordModel;
use app\common\RootService;

class MoneyRecordService extends RootService
{
    /**
     * 添加资金流水
     * @param array $params
     * @return MoneyRecordModel|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function add(array $params) {
        // 操作金额
        $amount = $params['amount'];
        // 收支类型
        $type = $params['type'] ?? MONEY_INCOME;
        // 状态
        $state = $params['state'] ?? MONEY_RECORD_STATE_FIELD;
        // 货币类型
        $currency = $params['currency'] ?? CURRENCY_COIN;
        // 用户ID
        $memberId = $params['memberId'] ?? $this->memberId;
        // 更新账户金额
        $renewCensus = $params['renewCensus'] ?? true;
        // 资金流水
        $recordData = ['member_id' => $memberId, 'currency' => $currency, 'type' => $type, 'state' => $state,
            'amount' => $amount, 'method' => $params['method'] ?? MONEY_RECORD_METHOD_DUTY, 'write_date' => date('Y-m-d')];
        // 交易完成更新统计数据
        if (($recordInfo = MoneyRecordModel::create($recordData)) && $state == MONEY_RECORD_STATE_COMPLETE && $renewCensus) {
            $censusInfo = $this->censusInfo($currency, $type, $memberId);
            $censusInfo->amount += $amount;
            $censusInfo->save();
        }
        return $recordInfo;
    }

    /**
     * 添加资金流水（遇到异常自动回滚）
     * @param array $params
     * @return MoneyRecordModel|\think\Model|void
     * @throws \app\common\RootException
     */
    public function addCatch(array $params)
    {
        $moneyRecordModel = new MoneyRecordModel();
        try {
            $moneyRecordModel->startTrans();
            $recordInfo = $this->add($params);
            $moneyRecordModel->commit();
            return $recordInfo;
        } catch (\Exception $e) {
            $moneyRecordModel->rollback();
            $this->errorException(lang('operation failed'));
        }
    }

    /**
     * 更新状态
     * @param int $recordId
     * @param int $state
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function renewState(int $recordId, int $state)
    {
        if ($recordInfo = MoneyRecordModel::where(['id' => $recordId])->find()) {
            $recordInfo->state = $state;
            $recordInfo->save();
            // 交易完成更新统计数据
            if ($state == MONEY_RECORD_STATE_COMPLETE) {
                $censusInfo = $this->censusInfo($recordInfo['currency'], $recordInfo['type'], $recordInfo['member_id']);
                $censusInfo->amount += $recordInfo['amount'];
                $censusInfo->save();
            }
        }
    }

    /**
     * 更新状态（遇到异常自动回滚）
     * @param int $recordId
     * @param int $state
     * @throws \app\common\RootException
     */
    public function renewStateCatch(int $recordId, int $state)
    {
        $moneyRecordModel = new MoneyRecordModel();
        try {
            $moneyRecordModel->startTrans();
            $this->renewState($recordId, $state);
            $moneyRecordModel->commit();
        } catch (\Exception $e) {
            $moneyRecordModel->rollback();
            $this->errorException(lang('operation failed'));
        }
    }

    /**
     * 获取资金统计
     * @param int $currency
     * @param int $type
     * @param int $memberId
     * @return MoneyCensusModel|array|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function censusInfo(int $currency, int $type, int $memberId)
    {
        // 筛选条件
        $where = ['member_id' => $memberId, 'currency' => $currency, 'type' => $type];
        // 筛选结果
        if (!$censusInfo = MoneyCensusModel::where($where)->find()) {
            $censusInfo = MoneyCensusModel::create($where);
        }
        return $censusInfo;
    }
}